Refs 和 DOM
概述
在 React 中,Refs 提供了一种访问 DOM 节点或 React 元素的方式。通常情况下,我们通过状态和属性来管理组件的交互和渲染,但在某些情况下,直接操作 DOM 是必要的。Refs 允许我们在不使用状态的情况下直接与 DOM 进行交互。
为什么需要 Refs?
- 操作 DOM 元素:例如,聚焦输入框、触发动画、集成第三方 DOM 库等。
- 存储前一个状态:在某些情况下,你可能需要存储组件的前一个状态。
- 避免重新渲染:通过 Refs,你可以在不触发组件重新渲染的情况下访问和修改 DOM 元素。
创建 Refs
在 React 中,Refs 可以通过 React.createRef() 或 useRef() Hook 来创建。
使用 React.createRef()
import React, { Component } from 'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount() {
this.myRef.current.focus();
}
render() {
return <input ref={this.myRef} />;
}
}
使用 useRef() Hook
import React, { useRef, useEffect } from 'react';
function MyComponent() {
const myRef = useRef(null);
useEffect(() => {
myRef.current.focus();
}, []);
return <input ref={myRef} />;
}
访问 Refs
Refs 通过 .current 属性来访问 DOM 节点或组件实例。
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} />;
使用 Refs 的场景
1. 聚焦输入框
import React, { useRef, useEffect } from 'react';
function FocusInput() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} />;
}
2. 触发动画
import React, { useRef, useEffect } from 'react';
function AnimateBox() {
const boxRef = useRef(null);
useEffect(() => {
boxRef.current.style.transform = 'translateX(100px)';
}, []);
return <div ref={boxRef} style={{ width: '100px', height: '100px', background: 'red' }} />;
}
3. 集成第三方 DOM 库
import React, { useRef, useEffect } from 'react';
import * as d3 from 'd3';
function D3Chart() {
const chartRef = useRef(null);
useEffect(() => {
const svg = d3.select(chartRef.current)
.append('svg')
.attr('width', 500)
.attr('height', 500);
svg.append('circle')
.attr('cx', 250)
.attr('cy', 250)
.attr('r', 50)
.attr('fill', 'blue');
}, []);
return <div ref={chartRef} />;
}
实践练习
练习 1: 聚焦输入框
创建一个组件,当组件挂载时,自动聚焦到一个输入框。
import React, { useRef, useEffect } from 'react';
function AutoFocusInput() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} placeholder="自动聚焦" />;
}
export default AutoFocusInput;
练习 2: 触发按钮点击
创建一个按钮,当组件挂载时,自动触发按钮的点击事件。
import React, { useRef, useEffect } from 'react';
function AutoClickButton() {
const buttonRef = useRef(null);
useEffect(() => {
buttonRef.current.click();
}, []);
return <button ref={buttonRef}>自动点击</button>;
}
export default AutoClickButton;
练习 3: 集成第三方库
使用 useRef 集成一个简单的第三方库,例如 moment.js,在组件挂载时显示当前时间。
import React, { useRef, useEffect } from 'react';
import moment from 'moment';
function CurrentTime() {
const timeRef = useRef(null);
useEffect(() => {
timeRef.current.textContent = moment().format('MMMM Do YYYY, h:mm:ss a');
}, []);
return <div ref={timeRef} />;
}
export default CurrentTime;
总结
Refs 是 React 中一个强大的工具,允许你直接访问和操作 DOM 元素。通过 React.createRef() 或 useRef() Hook,你可以轻松地在组件中创建和使用 Refs。尽管 Refs 非常有用,但在大多数情况下,你应该优先考虑使用状态和属性来管理组件的交互和渲染。
在下一节中,我们将探讨 useState 和 useEffect Hooks,它们是 React 中管理状态和副作用的核心工具。